package org.pentaho.di.ui.core.widget;

import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.ui.core.FormDataBuilder;
import org.pentaho.di.ui.core.PropsUI;
import org.pentaho.di.ui.core.WidgetUtils;
import org.pentaho.di.ui.util.SwtSvgImageUtil;

public class TopicSelection extends Composite {
    private final PropsUI props;
    private final TransMeta transMeta;
    private final BaseStepMeta stepMeta;
    private final ModifyListener lsMod;
    private final boolean topicInField;
    private final String topicGroupLabel;
    private final String fieldTopicLabel;
    private final String fieldTopicErrorToolTip;
    private final String textTopicLabel;
    private final String textTopicRadioLabel;
    private final String fieldTopicRadioLabel;
    private final boolean displayTopicErrorIcon;
    private Group wTopicGroup;
    private Button wTopicFromField;
    private Button wTopicFromText;
    private Label wlTopic;
    private Label wlConnectionError;
    private boolean isTopicTextCombo;
    private TextVar wTopicText;
    private ComboVar wTopicTextCombo;
    private ComboVar wTopicField;

    private TopicSelection(TopicSelection.Builder builder) {
        super(builder.composite, builder.style);
        this.props = builder.props;
        this.transMeta = builder.transMeta;
        this.stepMeta = builder.stepMeta;
        this.lsMod = builder.lsMod;
        this.topicInField = builder.topicInField;
        this.topicGroupLabel = builder.topicGroupLabel;
        this.fieldTopicLabel = builder.fieldTopicLabel;
        this.fieldTopicErrorToolTip = builder.fieldTopicErrorToolTip;
        this.textTopicLabel = builder.textTopicLabel;
        this.textTopicRadioLabel = builder.textTopicRadioLabel;
        this.fieldTopicRadioLabel = builder.fieldTopicRadioLabel;
        this.isTopicTextCombo = builder.isTopicTextCombo;
        this.displayTopicErrorIcon = builder.displayTopicErrorIcon;
        this.layoutUI();
    }

    private void layoutUI() {
        FormLayout topicSelectionLayout = new FormLayout();
        this.setLayout(topicSelectionLayout);
        this.wTopicGroup = new Group(this, 16);
        this.props.setLook(this.wTopicGroup);
        this.wTopicGroup.setText(this.topicGroupLabel);
        FormLayout topicGroupLayout = new FormLayout();
        topicGroupLayout.marginHeight = 15;
        topicGroupLayout.marginWidth = 15;
        this.wTopicGroup.setLayout(topicGroupLayout);
        this.wTopicGroup.setLayoutData((new FormDataBuilder()).top(0, 10).fullWidth().bottom().result());
        this.wTopicFromText = new Button(this.wTopicGroup, 16);
        this.wTopicFromField = new Button(this.wTopicGroup, 16);
        this.props.setLook(this.wTopicFromText);
        this.props.setLook(this.wTopicFromField);
        SelectionAdapter selectionListener = new SelectionAdapter() {
            public void widgetSelected(SelectionEvent selectionEvent) {
                super.widgetSelected(selectionEvent);
                TopicSelection.this.setTopicWidgetVisibility(TopicSelection.this.wTopicFromField);
            }
        };
        this.wTopicFromField.addSelectionListener(selectionListener);
        this.wTopicFromText.addSelectionListener(selectionListener);
        this.wTopicFromField.setSelection(this.topicInField);
        this.wTopicFromText.setSelection(!this.topicInField);
        this.wTopicFromText.setText(this.textTopicRadioLabel);
        this.wTopicFromField.setText(this.fieldTopicRadioLabel);
        this.wTopicFromText.setLayoutData((new FormDataBuilder()).left().top().result());
        this.wTopicFromField.setLayoutData((new FormDataBuilder()).left().top(this.wTopicFromText).result());
        this.wTopicFromField.addSelectionListener(selectionListener);
        this.wTopicFromText.addSelectionListener(selectionListener);
        Label separator = new Label(this.wTopicGroup, 514);
        separator.setLayoutData((new FormDataBuilder()).top().left(this.wTopicFromField, 15).bottom().result());
        this.wlTopic = new Label(this.wTopicGroup, 16384);
        this.props.setLook(this.wlTopic);
        if (this.displayTopicErrorIcon) {
            this.wlTopic.setLayoutData((new FormDataBuilder()).top().left(separator, 15).result());
            this.wlConnectionError = new Label(this.wTopicGroup, 16384);
            this.wlConnectionError.setToolTipText(this.fieldTopicErrorToolTip);
            this.wlConnectionError.setImage(SwtSvgImageUtil.getImage(this.getDisplay(), this.getClass().getClassLoader(), "error.svg", 16, 16));
            this.props.setLook(this.wlConnectionError);
            this.wlConnectionError.setLayoutData((new FormDataBuilder()).top().left(this.wlTopic, 4).result());
            this.wlConnectionError.setVisible(false);
        } else {
            this.wlTopic.setLayoutData((new FormDataBuilder()).top().left(separator, 15).right().result());
        }

        FormData fdTopic = (new FormDataBuilder()).top(this.wlTopic).left(separator, 15).right().result();
        this.wTopicTextCombo = new ComboVar(this.transMeta, this.wTopicGroup, 18436);
        this.props.setLook(this.wTopicTextCombo);
        this.wTopicTextCombo.setLayoutData(fdTopic);
        this.wTopicTextCombo.addModifyListener(this.lsMod);
        this.wTopicText = new TextVar(this.transMeta, this.wTopicGroup, 18436);
        this.props.setLook(this.wTopicText);
        this.wTopicText.setLayoutData(fdTopic);
        this.wTopicText.addModifyListener(this.lsMod);
        this.wTopicField = WidgetUtils.createFieldDropDown(this.wTopicGroup, this.props, this.stepMeta, fdTopic);
        this.props.setLook(this.wTopicField);
        this.wTopicField.setLayoutData(fdTopic);
        this.setTopicWidgetVisibility(this.wTopicFromField);
        this.wTopicField.addModifyListener(this.lsMod);
    }

    private void setTopicWidgetVisibility(Button topicComesFromField) {
        this.stepMeta.setChanged(this.stepMeta.hasChanged() || this.topicInField != topicComesFromField.getSelection());
        this.wTopicField.setVisible(topicComesFromField.getSelection());
        if (topicComesFromField.getSelection()) {
            this.wlTopic.setText(this.fieldTopicLabel);
            this.wTopicTextCombo.setVisible(false);
            this.wTopicText.setVisible(false);
            if (this.displayTopicErrorIcon) {
                this.wlConnectionError.setVisible(false);
            }
        } else {
            this.wlTopic.setText(this.textTopicLabel);
            this.toggleTopicTextComboVisible(this.isTopicTextCombo);
        }

    }

    public void setIsTopicTextCombo(boolean isCombo) {
        this.isTopicTextCombo = isCombo;
    }

    public void toggleTopicTextComboVisible(boolean isComboVisible) {
        if (!this.wTopicFromField.getSelection()) {
            if (this.displayTopicErrorIcon) {
                this.wlConnectionError.setVisible(!isComboVisible);
            }

            this.wTopicTextCombo.setVisible(isComboVisible);
            this.wTopicText.setVisible(!isComboVisible);
        }

    }

    public String getTopicText() {
        return this.isTopicTextCombo ? this.wTopicTextCombo.getText() : this.wTopicText.getText();
    }

    public String getTopicFieldText() {
        return this.wTopicField.getText();
    }

    public void setTopicFieldText(String selectedTopicFieldText) {
        this.wTopicField.setText(selectedTopicFieldText);
    }

    public void setTopicText(String topicText) {
        this.wTopicTextCombo.setText(topicText);
        this.wTopicText.setText(topicText);
    }

    public void setTopicInField(boolean topicInField) {
        this.wTopicFromField.setSelection(topicInField);
        this.wTopicFromText.setSelection(!topicInField);
        this.setTopicWidgetVisibility(this.wTopicFromField);
    }

    public boolean isTopicInField() {
        return this.wTopicFromField.getSelection();
    }

    public void setEnabled(boolean enabled) {
        this.wTopicGroup.setEnabled(enabled);
        this.wTopicFromField.setEnabled(enabled);
        this.wTopicFromText.setEnabled(enabled);
        this.wlTopic.setEnabled(enabled);
        if (this.isTopicTextCombo) {
            this.wTopicTextCombo.setEnabled(enabled);
            this.wTopicTextCombo.setEditable(enabled);
        } else {
            this.wTopicText.setEnabled(enabled);
            this.wTopicText.setEditable(enabled);
        }

        this.wTopicField.setEnabled(enabled);
        this.wTopicField.setEditable(enabled);
    }

    public ComboVar getTopicTextCombo() {
        return this.wTopicTextCombo;
    }

    public TextVar getTopicTextComponent() {
        return this.wTopicText;
    }

    public static final class Builder {
        private Composite composite;
        private int style;
        private PropsUI props;
        private TransMeta transMeta;
        private BaseStepMeta stepMeta;
        private ModifyListener lsMod;
        private boolean topicInField;
        private String topicGroupLabel;
        private String fieldTopicLabel;
        private String fieldTopicErrorToolTip;
        private String textTopicLabel;
        private String textTopicRadioLabel;
        private String fieldTopicRadioLabel;
        private boolean isTopicTextCombo;
        private boolean displayTopicErrorIcon = false;

        public Builder() {
        }

        public TopicSelection.Builder setComposite(Composite composite) {
            this.composite = composite;
            return this;
        }

        public TopicSelection.Builder setStyle(int style) {
            this.style = style;
            return this;
        }

        public TopicSelection.Builder setProps(PropsUI props) {
            this.props = props;
            return this;
        }

        public TopicSelection.Builder setTransMeta(TransMeta transMeta) {
            this.transMeta = transMeta;
            return this;
        }

        public TopicSelection.Builder setStepMeta(BaseStepMeta stepMeta) {
            this.stepMeta = stepMeta;
            return this;
        }

        public TopicSelection.Builder setLsMod(ModifyListener lsMod) {
            this.lsMod = lsMod;
            return this;
        }

        public TopicSelection.Builder setTopicInField(boolean topicInField) {
            this.topicInField = topicInField;
            return this;
        }

        public TopicSelection.Builder setTopicGroupLabel(String topicGroupLabel) {
            this.topicGroupLabel = topicGroupLabel;
            return this;
        }

        public TopicSelection.Builder setFieldTopicLabel(String fieldTopicLabel) {
            this.fieldTopicLabel = fieldTopicLabel;
            return this;
        }

        public TopicSelection.Builder setTextTopicLabel(String textTopicLabel) {
            this.textTopicLabel = textTopicLabel;
            return this;
        }

        public TopicSelection.Builder setFieldTopicErrorToolTip(String fieldTopicErrorToolTip) {
            this.fieldTopicErrorToolTip = fieldTopicErrorToolTip;
            return this;
        }

        public TopicSelection.Builder isDisplayTopicErrorIcon(boolean displayTopicErrorIcon) {
            this.displayTopicErrorIcon = displayTopicErrorIcon;
            return this;
        }

        public TopicSelection.Builder setTextTopicRadioLabel(String textTopicRadioLabel) {
            this.textTopicRadioLabel = textTopicRadioLabel;
            return this;
        }

        public TopicSelection.Builder setFieldTopicRadioLabel(String fieldTopicRadioLabel) {
            this.fieldTopicRadioLabel = fieldTopicRadioLabel;
            return this;
        }

        public TopicSelection.Builder isFieldTextCombo(boolean isCombo) {
            this.isTopicTextCombo = isCombo;
            return this;
        }

        public TopicSelection build() {
            return new TopicSelection(this);
        }
    }
}
